package cn.tristenstudy.blog.service.impl;

import cn.tristenstudy.blog.exception.MyNotFoundException;
import cn.tristenstudy.blog.mapper.BlogMapper;
import cn.tristenstudy.blog.mapper.BlogTagMapper;
import cn.tristenstudy.blog.mapper.TagMapper;
import cn.tristenstudy.blog.pojo.Blog;
import cn.tristenstudy.blog.pojo.BlogTag;
import cn.tristenstudy.blog.pojo.Tag;
import cn.tristenstudy.blog.pojo.dto.TagDTO;
import cn.tristenstudy.blog.pojo.vo.BlogQuery;
import cn.tristenstudy.blog.service.TagService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xichen1.li
 * @date 2020-12-28 20:14
 */
@Service
public class TagServiceImpl implements TagService {

    @Autowired
    TagMapper tagMapper;
    @Autowired
    BlogMapper blogMapper;
    @Autowired
    BlogTagMapper blogTagMapper;

    @Transactional
    @Override
    public Boolean saveTag(Tag tag) {
        tag.setCreateTime(new Date());
        tag.setUpdateTime(new Date());
        int insert = tagMapper.insert(tag);
        return insert > 0;
    }

    @Transactional
    @Override
    public Tag getTag(Long id) {
        return tagMapper.selectById(id);
    }

    @Transactional
    @Override
    public Page<Tag> listTag(Long current) {
        Page<Tag> page = new Page<>();
        page.setCurrent(current);
        page.setSize(3);
        return tagMapper.selectByCondition(page);
    }

    @Override
    public List<Tag> list() {
        QueryWrapper<Tag> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag", 0);
        queryWrapper.select("id", "name");
        queryWrapper.orderByDesc("create_time");
        return tagMapper.selectList(queryWrapper);
    }

    @Override
    public List<TagDTO> listTagTop(Integer size) {
        QueryWrapper<Tag> tagQueryWrapper = new QueryWrapper<>();
        tagQueryWrapper.select("id", "name");
        tagQueryWrapper.eq("del_flag", 0);
        List<Tag> tagList = tagMapper.selectList(tagQueryWrapper);
        List<TagDTO> result = new ArrayList<>();
        for (Tag tag : tagList) {
            TagDTO tagDTO = new TagDTO();
            tagDTO.setId(tag.getId());
            tagDTO.setName(tag.getName());
            QueryWrapper<BlogTag> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tag_id", tag.getId());
            queryWrapper.eq("published", true);
            Integer count = blogTagMapper.selectCount(queryWrapper);
            tagDTO.setBlogCount(count);
            result.add(tagDTO);
        }
        return result.stream()
                .sorted((tag1, tag2) -> tag2.getBlogCount() - tag1.getBlogCount())
                .limit(size)
                .collect(Collectors.toList());
    }

    @Transactional
    @Override
    public Boolean updateTag(Tag tag) {
        Tag select = tagMapper.selectById(tag.getId());
        if (select == null) {
            throw new MyNotFoundException("标签不存在！");
        }
        tag.setUpdateTime(new Date());
        int rows = tagMapper.updateById(tag);
        return rows > 0;
    }

    @Transactional
    @Override
    public Boolean deleteTag(Long id) {
        Tag tag = tagMapper.selectById(id);
        if (tag == null) {
            throw new MyNotFoundException("标签不存在！");
        }
        tag.setDelFlag(1);
        tag.setUpdateTime(new Date());
        int row = tagMapper.updateById(tag);
        return row > 0;
    }

    @Override
    public boolean isNotExist(Tag tag) {
        return tagMapper.selectByName(tag.getName()) == null;
    }

    @Override
    public Page<Blog> listBlogByTagId(Long id, Integer current) {
        QueryWrapper<BlogTag> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tag_id", id);
        queryWrapper.eq("published", true);
        List<BlogTag> blogTagList = blogTagMapper.selectList(queryWrapper);
        ArrayList<Long> list = new ArrayList<>();
        for (BlogTag blogTag : blogTagList) {
            list.add(blogTag.getBlogId());
        }
        BlogQuery blogQuery = new BlogQuery();
        blogQuery.setPublished(true);
        blogQuery.setCurrent(current);
        if (list.size() == 0) {
            list.add(-1L);
        }
        blogQuery.setBlogIdList(list);
        Page<Blog> blogPage = blogMapper.listBlog(blogQuery);
        List<Blog> blogList = blogPage.getRecords();
        for (Blog blog : blogList) {
            Long blogId = blog.getId();
            List<Tag> tagList = tagMapper.selectByBlogId(blogId);
            blog.setTagList(tagList);
        }
        blogPage.setRecords(blogList);
        return blogPage;
    }
}
